#include "hplczkysprotocolcommon.h"
#include "hplczkyspfcid.h"
#include "hplczkyspacketformat.h"
#include "hplczkysfindpacket.h"
#include "hplczkysprotocolcommondata.h"
#include "hplczkysparsecommonpacket.h"
#include "hplczkysparsecommonsystempacket.h"
#include "hplczkysmakepacket.h"
#include "hplczkyssendcommonpacket.h"
#include "hplczkyssendcommonsystempacket.h"

#include "common/convert.h"

#include <QDebug>
#include "modulehplccmdid.h"
#include <QVariant>

namespace hplc
{
namespace zkys
{

HplcZkysProtocolCommon::HplcZkysProtocolCommon(CommonParam &param, QObject *parent)
    : HplcZkysProtocolCommon(*new HplcZkysProtocolCommonData(), param, parent)
{

}

HplcZkysProtocolCommon::HplcZkysProtocolCommon(HplcZkysProtocolCommonData &data, CommonParam &param, QObject *parent)
    : BaseProtocol (data, parent)
{
    HplcZkysMakePacket *maker = new HplcZkysMakePacket(data);
    HplcZkysCheckPacket *checker = new HplcZkysCheckPacket(data, this);

    HplcZkysParseCommonSystemPacket *commonSystemParser = new HplcZkysParseCommonSystemPacket(data, param, this);
    HplcZkysSendCommonSystemPacket *commonSystemSender = new HplcZkysSendCommonSystemPacket(data);

    data.m_maker = maker;
    data.m_checker = checker;
    data.m_commonSystemParser = commonSystemParser;
    data.m_commonSystemSender = commonSystemSender;

    connect(commonSystemParser, &HplcZkysParseCommonSystemPacket::setModel, this, &HplcZkysProtocolCommon::setModel);
    connect(commonSystemParser, &HplcZkysParseCommonSystemPacket::parseCompleted, this, &HplcZkysProtocolCommon::parseCompleted);
}

HplcZkysProtocolCommon::~HplcZkysProtocolCommon()
{
    HplcZkysProtocolCommonData *m_d = static_cast<HplcZkysProtocolCommonData*>(this->m_d);
    delete m_d->m_maker;
    delete m_d->m_checker;
    delete m_d->m_commonSystemParser;
    delete m_d->m_commonSystemSender;
}

bool HplcZkysProtocolCommon::setConfig(int id, const QVariant &var)
{
    switch (id)
    {
        case 0:
        {
            quint8 address = var.toUInt();
            HplcZkysProtocolCommonData *m_d = static_cast<HplcZkysProtocolCommonData*>(this->m_d);
            m_d->m_address = address;
        }
        break;
        default:
        return false;
        break;
    }
    return true;
}

bool HplcZkysProtocolCommon::getConfig(int id, QVariant &var)
{
    switch (id)
    {
        case 0:
        {
            HplcZkysProtocolCommonData *m_d = static_cast<HplcZkysProtocolCommonData*>(this->m_d);
            var.setValue(m_d->m_address);
        }
        break;
        default:
        return false;
        break;
    }
    return true;
}

bool HplcZkysProtocolCommon::setProtocolCmd(int id, QVariant &var)
{
    switch (id)
    {
        // common
        case hplc::CommonCmdID_SetDeviceAddress:
            getCommonSender()->setDeviceAddress(var.toUInt());
        break;
        case hplc::CommonCmdID_SetSyncTime:
            getCommonSender()->setSyncTime(var.toUInt());
        break;
        case hplc::CommonCmdID_SetOutput:
            {
            hplc::Output output = var.value<hplc::Output>();
            getCommonSender()->setOutput(output.number, output.level);
            }
        break;
        case hplc::CommonCmdID_SetTick:
            getCommonSender()->setTick();
        break;
        case hplc::CommonCmdID_SetTickPeriod:
            getCommonSender()->setTickPeriod(var.toUInt());
        break;
        case hplc::CommonCmdID_SetSystemErrorUploadFreq:
            getCommonSender()->setSystemErrorUploadFreq(var.toUInt());
        break;

        // common system
        case hplc::CommonSystemCmdID_SetReset:
            getCommonSystemSender()->setReset();
        break;
        case hplc::CommonSystemCmdID_SetRestoreDefault:
            getCommonSystemSender()->setRestoreDefault(var.toUInt());
        break;
        case hplc::CommonSystemCmdID_SetSaveAsDefault:
            getCommonSystemSender()->setSaveAsDefault();
        break;
        case hplc::CommonSystemCmdID_SetSuperPassword:
            {
            QString tmp = var.toString();
            char *p = tmp.toUtf8().data();
            getCommonSystemSender()->setSuperPassword(p);
            }
        break;
        case hplc::CommonSystemCmdID_SetProductDate:
            {
            QString tmp = var.toString();
            char *p = tmp.toUtf8().data();
            getCommonSystemSender()->setProductDate(p);
            }
        break;
        case hplc::CommonSystemCmdID_SetSerialNumber:
            {
            QString tmp = var.toString();
            char *p = tmp.toUtf8().data();
            getCommonSystemSender()->setSerialNumber(p);
            }
        break;
        case hplc::CommonSystemCmdID_SetModel:
            getCommonSystemSender()->setModel(var.toUInt());
        break;
        case hplc::CommonSystemCmdID_SetModelString:
            {
            QString tmp = var.toString();
            char *p = tmp.toUtf8().data();
            getCommonSystemSender()->setModelString(p);
            }
        break;
        case hplc::CommonSystemCmdID_SetUsedTime:
            getCommonSystemSender()->setUsedTime(var.toUInt());
        break;
        case hplc::CommonSystemCmdID_SetProtocol:
            getCommonSystemSender()->setProtocol(var.toUInt());
        break;
        case hplc::CommonSystemCmdID_SetDebugPort:
            getCommonSystemSender()->setDebugPort(var.toUInt());
        break;
        case hplc::CommonSystemCmdID_SetDebugVariants:
            getCommonSystemSender()->setPrintVariants();
        break;
        default:
            return false;
        break;
    }
    return true;
}

bool HplcZkysProtocolCommon::getProtocolCmd(int id, QVariant &var)
{
    switch (id)
    {
        // common
        case hplc::CommonCmdID_GetDeviceAddress:
            getCommonSender()->getDeviceAddress();
        break;
        case hplc::CommonCmdID_GetSoftwareVersion:
            getCommonSender()->getSoftwareVersion();
        break;
        case hplc::CommonCmdID_GetHardwareVersion:
            getCommonSender()->getHardwareVersion();
        break;
        case hplc::CommonCmdID_GetProductDate:
            getCommonSender()->getProductDate();
        break;
        case hplc::CommonCmdID_GetSerialNumber:
            getCommonSender()->getSerialNumber();
        break;
        case hplc::CommonCmdID_GetModel:
            getCommonSender()->getModel();
        break;
        case hplc::CommonCmdID_GetUsedTime:
            getCommonSender()->getUsedTime();
        break;
        case hplc::CommonCmdID_GetSyncTime:
            getCommonSender()->getSyncTime();
        break;
        case hplc::CommonCmdID_GetInput:
            getCommonSender()->getInput(var.toUInt());
        break;
        case hplc::CommonCmdID_GetOutput:
            getCommonSender()->getOutput(var.toUInt());
        break;
        case hplc::CommonCmdID_GetTickPeriod:
            getCommonSender()->getTickPeriod();
        break;
        case hplc::CommonCmdID_GetSystemError:
            getCommonSender()->getSystemError();
        break;
        case hplc::CommonCmdID_GetSystemErrorUploadFreq:
            getCommonSender()->getSystemErrorUploadFreq();
        break;

        // common system
        case hplc::CommonSystemCmdID_GetSuperPassword:
            getCommonSystemSender()->getSuperPassword();
        break;
        case hplc::CommonSystemCmdID_GetSoftwareVersion:
            getCommonSystemSender()->getSoftwareVersion();
        break;
        case hplc::CommonSystemCmdID_GetHardwareVersion:
            getCommonSystemSender()->getHardwareVersion();
        break;
        case hplc::CommonSystemCmdID_GetProductDate:
            getCommonSystemSender()->getProductDate();
        break;
        case hplc::CommonSystemCmdID_GetSerialNumber:
            getCommonSystemSender()->getSerialNumber();
        break;
        case hplc::CommonSystemCmdID_GetModel:
            getCommonSystemSender()->getModel();
        break;
        case hplc::CommonSystemCmdID_GetModelString:
            getCommonSystemSender()->getModelString();
        break;
        case hplc::CommonSystemCmdID_GetUsedTime:
            getCommonSystemSender()->getUsedTime();
        break;
        case hplc::CommonSystemCmdID_GetProtocol:
            getCommonSystemSender()->getProtocol();
        break;
        case hplc::CommonSystemCmdID_GetDebugPort:
            getCommonSystemSender()->getDebugPort();
        break;
        default:
            return false;
        break;
    }
    return true;
}

HplcZkysCheckPacket *HplcZkysProtocolCommon::getChecker()
{
    HplcZkysProtocolCommonData *m_d = static_cast<HplcZkysProtocolCommonData*>(this->m_d);
    return m_d->m_checker;
}

HplcZkysParseCommonPacket *HplcZkysProtocolCommon::getCommonParser()
{
    return static_cast<HplcZkysParseCommonPacket*>(m_d->m_parser);
}

HplcZkysSendCommonSystemPacket *HplcZkysProtocolCommon::getCommonSystemSender()
{
    HplcZkysProtocolCommonData *m_d = static_cast<HplcZkysProtocolCommonData*>(this->m_d);
    return m_d->m_commonSystemSender;
}

void HplcZkysProtocolCommon::setModel(quint8 model)
{
    Q_UNUSED(model)
}

HplcZkysParseCommonSystemPacket *HplcZkysProtocolCommon::getCommonSystemParser()
{
    HplcZkysProtocolCommonData *m_d = static_cast<HplcZkysProtocolCommonData*>(this->m_d);
    return m_d->m_commonSystemParser;
}

HplcZkysSendCommonPacket *HplcZkysProtocolCommon::getCommonSender()
{
    return static_cast<HplcZkysSendCommonPacket*>(m_d->m_sender);
}

void HplcZkysProtocolCommon::onBaseTickTimeout()
{
    HplcZkysProtocolCommonData *m_d = static_cast<HplcZkysProtocolCommonData*>(this->m_d);
    m_d->m_checker->onBaseTickTimeout();
}

} // zkys
} // hplc
